package types;

import java.io.*;
import java.lang.Math;
import java.util.ArrayList;
import java.util.List;

public class Parser extends helper_funcs {

	public static void initialize (File input){
		BufferedReader reader = null;

		try {
			String s;
			Double d;
			int j = 0; // number of edges
			int i;
			int vertices;
			String hash;
			
			int maxInt = Integer.MAX_VALUE;
			Double multiplier = 1.0;
			Double max = 0.0;

			Main.max_weight = 0;

			reader = new BufferedReader(new FileReader(input));

			vertices = Integer.parseInt(reader.readLine().substring(1).trim()); // this line will be our vertex array size
		//	System.err.println("there are " + vertices + " vertices");
			vertices++;

			Main.vertex_list.ensureCapacity(vertices);

			
			ArrayList <Short> source = new ArrayList <Short> (vertices * 10);
			ArrayList <Short> destination = new ArrayList <Short> (vertices * 10);
			ArrayList <Double> distance = new ArrayList <Double> (vertices * 10);
			String[] temp = new String[vertices*10];

			
			// parsing the file and putting the values into the arrays
			i = 0;
			
			while((s = reader.readLine()) != null) 
			{
				
				temp = s.split("\t");
				d = Double.parseDouble(temp[0]);
				source.add(d.shortValue());
				d = Double.parseDouble(temp[1]);
				destination.add(d.shortValue());
				d = Double.parseDouble(temp[2]);
				distance.add(d);	    		
				i++;				
			}
			
			for(int k = 0; k < vertices; k++)
			{
				Main.vertex_list.add(new Vertex());
				Main.vertex_by_destination.add(new Vertex());
			}

			/*
			for (int z = 0; z < distance.size(); z++)
			{
				if (max < distance.get(z))
				{
					max = (double) distance.get(z);
				}
			}
			*/
			/*
			while( (int) (max*multiplier) < maxInt)
			{
				multiplier = (multiplier *10);
			}
			multiplier = (multiplier/ 10);
			*/
			
			//Main.max_weight = ((int) (max * multiplier));
			
			// setting up the unsorted 'vertex' list
			for (i = 0; i < source.size(); i++)
			{
				Main.vertex_list.get(source.get(i)).edges.add(new Edge(source.get(i), destination.get(i), (int) (distance.get(i) * 1000.0)));
				Main.vertex_list.get(destination.get(i)).edges.add(new Edge(destination.get(i), source.get(i), (int) (distance.get(i) * 1000.0)));

				Main.vertex_by_destination.get(source.get(i)).edges.add(
						Main.vertex_list.get(destination.get(i)).edges.get
						(Main.vertex_list.get(destination.get(i)).edges.size()-1));

				Main.vertex_by_destination.get(destination.get(i)).edges.add(
						Main.vertex_list.get(source.get(i)).edges.get
						(Main.vertex_list.get(source.get(i)).edges.size()-1));

				hash = destination.get(i)+ "," + source.get(i);
				Main.vertex_hash.put (hash,  Main.vertex_list.get(destination.get(i)).edges.get
						(Main.vertex_list.get(destination.get(i)).edges.size()-1));

				hash = source.get(i)+ "," + destination.get(i);
				Main.vertex_hash.put (hash,  Main.vertex_list.get(source.get(i)).edges.get
						(Main.vertex_list.get(source.get(i)).edges.size()-1));		



				if (distance.get(i) > max) { max = distance.get(i); }
			}

			Main.max_weight = (int) (max * 10000.0);

			// placing edge arrays into Vertex class instances in vertex_list
			for (i = 1; i < vertices; i++) 
			{
				edge_sort(Main.vertex_list.get(i).edges);
				edge_sort(Main.vertex_by_destination.get(i).edges);

				Main.vertex_list.get(i).valid_count = (short) Main.vertex_list.get(i).edges.size();
				//vertex_list[i].edges_valid = quicksort(vertex_list[i].edges_valid, 0, vertex_list.length);
			}


		}
		catch (Exception e) {System.err.println("error");
			//e.printStackTrace();}    
		}

	}

	// writes the solution to a file
	public static void write_solution(Solution solution, File file)
	{		
		int next = 1;
		BufferedWriter writer = null;
		try {
			writer = new BufferedWriter(new FileWriter(file));
			writer.write("1");
			writer.newLine();
			for (int i = 1; i < solution.edges.size(); i++)
			{
				writer.write("" + solution.edges.get(next).getDestination());
				writer.newLine();
				writer.flush();
				next = solution.edges.get(next).getDestination();
				if (next == -1) {break;}
			}
			writer.close();

		}
		catch (Exception e) {e.printStackTrace();}  
	}

	// calculate the total distance found in the solution file
	public static int sol_dist(ArrayList <Vertex> vertex_list, File file){
		BufferedReader reader = null;

		int result = 0;
		int value;
		int i;

		int[] sol = new int[(vertex_list.size()-1)];

		try {
			reader = new BufferedReader(new FileReader(file));

			//save the vertex number into an array
			for(i = 0; (value = Integer.parseInt(reader.readLine())) != -1; i++) {
				sol[i] = value;
			}


		}
		catch (Exception e) {
			e.printStackTrace();
		}

		// determine the distance between two edges
		for(i = 0; i < sol.length-1; i++){
			result += vertex_list.get(sol[i]).getEdge(sol[i+1]).getWeight();
		}

		return result;
	}



	// function to avoid using try/catch for reading in files
	public static BufferedReader readIn(File file) {
		BufferedReader reader = null;

		try {
			reader = new BufferedReader(new FileReader(file));
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return reader;
	}

static void print_sol2()
{
	int next = 1;
	for (int i = 1; i < Algorithms.solution.edges.size(); i++)
	{
		System.out.println(next);
		next = Algorithms.solution.edges.get(next).getDestination();
		//if (next == -1) {break;}
	}
	System.out.println(-1);
}
	// for validator use
	public static void sysPrintSol(Solution solution) {
		int next = 1;
		//System.out.println("1");
		for (int i = 1; i < solution.edges.size(); i++) {
			System.out.print(next + "\n");
			//System.err.print(next + "\n");
			next = solution.edges.get(next).getDestination();
		}
		System.out.print("-1");
		//System.err.print("-1");
		
		//System.exit(0);
	}

	
	
}
